﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Description;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using HospitalDbSecure.Models;

namespace HospitalDbSecure.Controllers
{
    [Authorize]
    [RoutePrefix("api/Patient")]
    public class PatientController : ApiController
    {
        private HospitalEntities hospitalDb = new HospitalEntities();
        private UsersEntities usersDb = new UsersEntities();
        private AspnetIdentityEntities identityDb = new AspnetIdentityEntities();

        // GET Patient List for User
        //[AllowAnonymous]
        [Route("List")]
        [ResponseType(typeof(Data))]
        public async Task<IHttpActionResult> GetPatientListForUser()
        {
            // Get ID of the logged-in User
            var userId = User.Identity.GetUserId();
            //var userId = "d834ce69-37b6-4440-bb53-107551ce52d1";

            // Get a list of patient IDs
            var patientIds = await usersDb.PatientLists.Where(pl => pl.UserId == userId).Select(pl => pl.PatientId).ToListAsync();

            // LINQ query to select patients from list
            var userPatients = await (from patient in hospitalDb.Patients
                                  join id in patientIds
                                  on patient.Id equals id
                                  select patient)
                                  .ToListAsync();

            // Get all patients in the database
            var allPatients = await hospitalDb.Patients.ToListAsync();

            // Get User Information
            var userInfo = usersDb.UserInformations.Where(u => u.UserId == userId).First();

            // Create Data instance
            Data data = new Data() { PatientList = userPatients,
                                     AllPatients = allPatients,
                                     UserInformation = userInfo };

            return Ok(data);
        }

        // GET api/Patient
        public IQueryable<Patient> GetPatients()
        {
            return hospitalDb.Patients;
        }

        // GET api/Patient/5
        [ResponseType(typeof(Patient))]
        public async Task<IHttpActionResult> GetPatient(int id)
        {
            Patient patient = await hospitalDb.Patients.FindAsync(id);
            if (patient == null)
            {
                return NotFound();
            }

            return Ok(patient);
        }

        // PUT api/Patient/5
        public async Task<IHttpActionResult> PutPatient(int id, Patient patient)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            if (id != patient.Id)
            {
                return BadRequest();
            }

            hospitalDb.Entry(patient).State = EntityState.Modified;

            try
            {
                await hospitalDb.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!PatientExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return StatusCode(HttpStatusCode.NoContent);
        }

        // POST api/Patient
        [ResponseType(typeof(Patient))]
        public async Task<IHttpActionResult> PostPatient(Patient patient)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            hospitalDb.Patients.Add(patient);
            await hospitalDb.SaveChangesAsync();

            return CreatedAtRoute("DefaultApi", new { id = patient.Id }, patient);
        }

        // DELETE api/Patient/5
        [ResponseType(typeof(Patient))]
        public async Task<IHttpActionResult> DeletePatient(int id)
        {
            Patient patient = await hospitalDb.Patients.FindAsync(id);
            if (patient == null)
            {
                return NotFound();
            }

            hospitalDb.Patients.Remove(patient);
            await hospitalDb.SaveChangesAsync();

            return Ok(patient);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                hospitalDb.Dispose();
            }
            base.Dispose(disposing);
        }

        private bool PatientExists(int id)
        {
            return hospitalDb.Patients.Count(e => e.Id == id) > 0;
        }
    }
}